#include "sCRIText.h"
#include "sCRText.h"
#include "sFontPreset.h"
#include "sGui.h"

#include <iostream>
#include <iterator>

namespace sgui
{
namespace inst
{

const std::wstring& sComponentRectText::getText() const
{
	return m_text;
}

void sComponentRectText::setText(const std::wstring& text)
{
	m_text = text;

	clear();
	std::wstringstream textStream(m_text);
    std::wstring item;
    while (std::getline(textStream, item, res::TEXT_RETURN_CHAR)) {
        sTextString* str = new sTextString(*this, item);
		m_strings.push_back(str);
    }
	updateText();
}
		
void sComponentRectText::clear()
{
	for (std::deque<sTextString*>::iterator it = m_strings.begin(); it != m_strings.end(); it++)
	{
		delete (*it);
	}
	m_strings.clear();
}
				
void sComponentRectText::draw(engine::sDrawStack& stack) const
{
	const res::sComponentRectText& m_object = get<res::sComponentRectText>();

	const preset::sFontPreset *preset = m_object.getFontPresetGroup().get(getState());
	if (preset)
	{
		const engine::sFont *font = preset->getFont();
		if (font)
		{
			const std::deque<sTextString*>& lines = m_strings;

			ALLOC_CONTEXT(stack.getGui().getEngine(), context, m_rect, stack.top(), m_object.getClipRect());

			if (stack.push(context))
			{
				for (std::deque<sTextString*>::const_iterator it = lines.begin(); it != lines.end(); it++)
				{
					sTextString *line = (*it);
					
					obj::sTransform t;
                    t.getPosition().set(line->getRect().getPosition());
					stack.top()->pushTransform(t);

					line->draw(stack);
					
					stack.top()->popTransform();			
					
				}

				stack.pop();
			}

			RELEASE_CONTEXT(context);
		}
	}
}
		
bool sComponentRectText::OnEvent(const obs::sEvent& event)
{
	if (sComponentRectInstance::OnEvent(event))
	{
		return true;
	}

	return false;
}

void sComponentRectText::update() 
{
	updateText();
}

void sComponentRectText::updateText()
{
	const res::sComponentRectText& m_object = get<res::sComponentRectText>();

	const preset::sFontPreset *preset = m_object.getFontPresetGroup().get(getState());
	if (preset)
	{
        getTextRect().setSize(math::sPointf(0, 0));

		const float v_coef = res::FONT_ALIGN_COEF[m_object.getVerticalAlign()];
		const float h_coef = res::FONT_ALIGN_COEF[m_object.getHorisontalAlign()];

		for (std::deque<sTextString*>::iterator it = m_strings.begin(); it != m_strings.end(); it++)
		{
			(*it)->update(preset);
			if (getTextRect().W < (*it)->getRect().W) getTextRect().W = (*it)->getRect().W;
			getTextRect().H += (*it)->getRect().H;
		}

        getTextRect().setPosition(math::sPointf(
			m_rect.W * h_coef - getTextRect().W * h_coef,
			m_rect.H * v_coef - getTextRect().H * v_coef
		));	
        float offset_y = 0;

		for (std::deque<sTextString*>::iterator it = m_strings.begin(); it != m_strings.end(); it++)
		{
            (*it)->getRect().setPosition(math::sPointf(
                getTextRect().X + (getTextRect().W * h_coef - (*it)->getRect().W * h_coef),
                getTextRect().Y + offset_y
            ));

			offset_y += (*it)->getRect().H;
		}
	}
}

sComponentRectText::~sComponentRectText()
{
	clear();
}

sComponentRectText::sComponentRectText(const res::sComponentRectText& componentRect, sComponentInstance& instance, s32 id) :
	sComponentRectInstance(componentRect, instance, id)
{
	updateText();
}

};
};